#ifndef __MILTER_H__
#define __MILTER_H__

#define MILTER_CHUNK_SIZE  UINT16_MAX

#define SMFIF_ADDHDRS      0x01
#define SMFIF_CHGBODY      0x02
#define SMFIF_ADDRCPT      0x04
#define SMFIF_DELRCPT      0x08
#define SMFIF_CHGHDRS      0x10
#define SMFIF_QUARANTINE   0x20
#define SMFIF_SETSENDER    0x40
#define SMFIF_MODBODY      SMFIF_CHGBODY

#define SMFI_V1_ACTS       (SMFIF_ADDHDRS|SMFIF_CHGBODY|SMFIF_ADDRCPT|SMFIF_DELRCPT)
#define SMFI_V2_ACTS       (SMFI_V1_ACTS|SMFIF_CHGHDRS)
#define SMFI_CURR_ACTS     (SMFI_V2_ACTS)

#define SMFIP_NOCONNECT    0x01
#define SMFIP_NOHELO       0x02
#define SMFIP_NOMAIL       0x04
#define SMFIP_NORCPT       0x08
#define SMFIP_NOBODY       0x10
#define SMFIP_NOHDRS       0x20
#define SMFIP_NOEOH        0x40
#define SMFIP_NONE         0x7F

#define SMFIC_ABORT        'A'
#define SMFIC_BODY         'B'
#define SMFIC_CONNECT      'C'
#define SMFIC_MACRO        'D'
#define SMFIC_BODYEOB      'E'
#define SMFIC_HELO         'H'
#define SMFIC_HEADER       'L'
#define SMFIC_MAIL         'M'
#define SMFIC_EOH          'N'
#define SMFIC_OPTNEG       'O'
#define SMFIC_RCPT         'R'
#define SMFIC_QUIT         'Q'
#define SMFIC_DATA         'T'
#define SMFIC_UNKNOWN      'U'

#define SMFIR_ADDRCPT      '+'
#define SMFIR_DELRCPT      '-'
#define SMFIR_ACCEPT       'a'
#define SMFIR_REPLBODY     'b'
#define SMFIR_CONTINUE     'c'
#define SMFIR_DISCARD      'd'
#define SMFIR_ADDHEADER    'h'
#define SMFIR_INSHEADER    'i'
#define SMFIR_CHGHEADER    'm'
#define SMFIR_PROGRESS     'p'
#define SMFIR_QUARANTINE   'q'
#define SMFIR_REJECT       'r'
#define SMFIR_SETSENDER    's'
#define SMFIR_TEMPFAIL     't'
#define SMFIR_REPLYCODE    'y'

#define SMFIS_CONTINUE     100
#define SMFIS_REJECT       101
#define SMFIS_DISCARD      102
#define SMFIS_ACCEPT       103
#define SMFIS_TEMPFAIL     104

#define SMFIA_UNKNOWN      'U'
#define SMFIA_UNIX         'L'
#define SMFIA_INET         '4'
#define SMFIA_INET6        '6'

struct milter_ctx {
    int sock;
    uint32_t actions;
    uint32_t protocols;
    uint8_t code;
    char *reply;
    SV *priv;
    HV *macro;
};

#define MILTER_CTX(rv) INT2PTR(struct milter_ctx *, SvIV((SV *)SvRV(rv)))

int write_packet(int sock, char code, char *buf, int len);

#endif
